package db

import (
	"context"
	mylogger "core/logger"
	"encoding/json"
	"go.uber.org/zap"
	"gorm.io/gorm/logger"
	"time"
)

type dbLog struct {
	LogLevel      logger.LogLevel
	SlowThreshold time.Duration
	ShowSql       bool
}

func NewGormLogger(cfg *DbConfig) *dbLog {
	var r = &dbLog{
		LogLevel:      logger.Info,
		SlowThreshold: time.Duration(cfg.SlowThreshold * 1000000),
		ShowSql:       cfg.ShowSql,
	}
	return r
}

func (l *dbLog) LogMode(level logger.LogLevel) logger.Interface {
	l.LogLevel = level
	return l
}

func (l *dbLog) Info(ctx context.Context, msg string, data ...interface{}) {
	//if l.LogLevel < logger.Info {
	//	return
	//}
	var buff, _ = json.Marshal(data)
	var sdata = string(buff)
	mylogger.Logger.Info(msg, zap.String("data", sdata))
}
func (l *dbLog) Warn(ctx context.Context, msg string, data ...interface{}) {
	//if l.LogLevel < logger.Warn {
	//	return
	//}

	var buff, _ = json.Marshal(data)
	var sdata = string(buff)
	mylogger.Logger.Warn(msg, zap.String("data", sdata))
}

func (l *dbLog) Error(ctx context.Context, msg string, data ...interface{}) {
	//if l.LogLevel < logger.Error {
	//	return
	//}
	var buff, _ = json.Marshal(data)
	var sdata = string(buff)
	mylogger.Logger.Error(msg, zap.String("data", sdata))
}

func (l *dbLog) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
	//这块的逻辑可以自己根据业务情况修改
	//if l.LogLevel < logger.Info {
	//	return
	//}
	elapsed := time.Since(begin)

	sql, rows := fc()

	// Gorm 错误时打印
	if err != nil {
		mylogger.Logger.Error(sql, zap.Error(err))
	} else {
		if l.SlowThreshold != 0 && elapsed > l.SlowThreshold {
			mylogger.Logger.Warn(sql,
				zap.Int64("rows", rows),
				zap.Duration("elapsed", elapsed),
				zap.Error(err),
				zap.String("SlowSql", "1"),
			)
		} else {
			if l.ShowSql {
				mylogger.Logger.Debug(sql,
					zap.Int64("rows", rows),
					zap.Duration("elapsed", elapsed),
					zap.Error(err),
				)
			}
		}
	}

}
